#pragma once

#include <iostream>
#include <pthread.h>
#include<string>
#include<cstdlib>

class Thread
{
    typedef enum
    {
        NEW = 0,
        RUNNING,
        EXITED
    } ThreadStatus;
    typedef void (*func_t)(void*);

public:
    Thread(int num,func_t func,void*args) : _tid(0), _status(NEW), _func(func),_args(args)
    {
        char name[128];
        snprintf(name, sizeof(name), "thread-%d", num);
        _name = name;
    }
    int status() { return _status; }
    std::string threadname() { return _name; }
    pthread_t threadid()
    {
        if (_status == RUNNING)
            return _tid;
        else
        {
            std::cout << "thread is not running,no tid" << std::endl;
            return 0;
        }
    }
    void operator()()
    {
        if(_func!=nullptr)
        _func(_args);
    }
    static void* runHelper(void*args)
    {
        Thread*ts=(Thread*)args;
    //    ts->_func(ts->_args);
        (*ts)();
        return nullptr;
    }
    void run()
    {
        int n=pthread_create(&_tid,nullptr,runHelper,this);
        if(n!=0)
            exit(1);
        _status=RUNNING;
    }
    void join()
    {
        int n=pthread_join(_tid,nullptr);
        if(n!=0)
        {
            std::cerr<<"main join thread"<<_name<<"error"<<std::endl;
            return;
        }
        _status=EXITED;
    }
    ~Thread()
    {
    }

private:
    pthread_t _tid;
    std::string _name;
    func_t _func;
    void* _args;
    ThreadStatus _status;
};